package com.mars.sso.web.controller;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.mars.common.utils.CommonUtils;
import com.mars.common.utils.CookieUtils;
import com.mars.common.utils.RandomUitl;
import com.mars.common.utils.WebUtil;
import com.mars.common.utils.date.DateUtil;
import com.mars.common.utils.security.PasswordUtils;
import com.mars.component.redis.JedisClient;
import com.mars.manager.user.entity.User;
import com.mars.manager.user.service.UserService;
import com.mars.web.common.pojo.ResponseResult;
import com.mars.web.common.support.BaseController;

/**
 * 后台管理系统登陆验证
 * @描述 TODO
 * @类名 SSOBossController
 * @日期 2016年12月20日 上午11:23:26
 * @作者 yhaoquan
 * @版权 (c) All Rights Reserved, 2016.
 */
@RestController
@RequestMapping("/boss")
public class SSOBossController extends BaseController {
	
	@Autowired
	private UserService userService ;
	
	@Autowired
	private JedisClient jedisClient ;
	
	/**
	 * SSO的Redis Session 的 KEY
	 */
	@Value("${SSO_REDIS_SESSION_KEY}")
	private String SSO_REDIS_SESSION_KEY ;
	
	/**
	 * Redis Session 的过期时间的KEY
	 */
	@Value("${SSO_REDIS_SESSION_EXPIRE}")
	private int SSO_REDIS_SESSION_EXPIRE ;
	
	/**
	 * 记录登陆密码错误次数的KEY
	 */
	@Value("${SSO_REDIS_PWD_ERROR_COUNT}")
	private String SSO_REDIS_PWD_ERROR_COUNT ;
	
	/**
	 * Cookie中Token的KEY 
	 */
	@Value("${SSO_COOKIE_TOKEN}")
	private String SSO_COOKIE_TOKEN ;
	
	@ApiOperation(value="Boss运维管理系统SSO登陆验证",  notes="", response=ResponseResult.class)
	@ApiImplicitParams({
		@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
		@ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String"),
		@ApiImplicitParam(name = "validate", value = "验证码", required = false, dataType = "String")
	})
	@RequestMapping(value="login", method=RequestMethod.POST)
	public Object login(String username, String password, String validate) {
		if(CommonUtils.isEmpty(username)) {
			return setResponseResult(400, "用户名不能为空");
		}
		if(CommonUtils.isEmpty(password)) {
			return setResponseResult(400, "密码不能为空") ;
		}
		
		Map<String, Object> msg = new HashMap<String, Object>() ;
		
		//取得登录密码错误次数，登录密码错误次数存放在缓存中
		String key = SSO_REDIS_PWD_ERROR_COUNT + ":" + username + ":" + request.getSession().getId() ;
		String passwordErrorCount = jedisClient.get(key);
		
		//密码错误次数等于3，需要输入验证码
		if(null != passwordErrorCount && Integer.parseInt(passwordErrorCount) > 3) {
			//显示验证码输入框
			msg.put("valid", true) ;
			//登录密码错误次数
			msg.put("passwordErrorCount", Integer.parseInt(passwordErrorCount)) ;
		}
		//验证码比较
		if(CommonUtils.isNotEmpty(msg.get("valid"))) {
			// TODO
		}
		
		//1. 根据用户名查找用户
		User user = this.userService.gerUserByUserName(username) ;
		if(null == user) {
			return setResponseResult(400, "用户名不存在", msg) ;
		}
		
		//2. 检查账号状态
		if (!user.getStatus()) {
			return setResponseResult(400, "该账号已被锁定，请联系管理员解锁。");
		}
		
		//3. 验证密码，如果密码错误
		if(!PasswordUtils.isPasswordValid(user.getPassword(), username, password, user.getSalt())) {
			//记录登录密码错误次数
			jedisClient.incr(key);
			jedisClient.expire(key, 600) ;
			
			//密码错误次数等于6，锁定账号
			if(null != passwordErrorCount && Integer.parseInt(passwordErrorCount) > 6) {
				try {
					if(user.getStatus()) {//账号状态未锁定情况下，才进行如下锁定操作
						this.userService.updateAccountStatus(user.getId(), false) ;
						logger.info("登录密码错误次数超过限定，将锁定账号：[{}]", username);
					}
				} catch (Exception e) {
					return setResponseResultError(e.getMessage()) ;
				}
			}
			return setResponseResult(400, "密码不正确",  msg) ;
		}
		//清除登录密码错误次数
		jedisClient.expire(key, 0) ;
		
		//4. 判断Cookie中是否存在token，存在则删除Cookie和RedisSession缓存
		String cookieToken = CookieUtils.getCookieValue(request, SSO_COOKIE_TOKEN) ;
		if(null != cookieToken) {
			//删除Cookie
			CookieUtils.deleteCookie(request, response, SSO_COOKIE_TOKEN);
			//删除缓存数据
			jedisClient.del(SSO_REDIS_SESSION_KEY+cookieToken);
		} 
		
		//5. 生成用户会话Token
		String token = RandomUitl.uuid() ;
		
		//密码设置未NULL
		user.setPassword(null);
		//6. 保存用户会话Token到Redis缓存
		jedisClient.set(SSO_REDIS_SESSION_KEY+token, JSON.toJSONString(user));
		jedisClient.expire(SSO_REDIS_SESSION_KEY+token, SSO_REDIS_SESSION_EXPIRE);
		
		//7. 设置用户会话Token到Cookie
		CookieUtils.setCookie(request, response, SSO_COOKIE_TOKEN, token);
		msg.put("token", token) ;
		return setResponseResult(true, "验证成功", msg) ;
	}
	
	
	@ApiOperation(value="获取当前登陆用户信息", notes="根据Token获取当前登陆用户信息", response=ResponseResult.class)
	@ApiImplicitParam(name="token", value="Cookie上的token信息", required=true, dataType="String")
	@GetMapping(value="getRedisSessionUser/{token}")
	public Object getUserByToken(@PathVariable String token) {
		String userJson = jedisClient.get(SSO_REDIS_SESSION_KEY+token) ;
		
		if(null == userJson) {
			return setResponseResultFailed("登陆超时，请重新登陆！") ;
		} else {
			//重置RedisSession的过期时间
			jedisClient.expire(SSO_REDIS_SESSION_KEY+token, SSO_REDIS_SESSION_EXPIRE);
			return setResponseResultOk("ok", userJson) ;
		}
	}
	
	@ApiOperation(value="删除当前登陆用户信息", notes="根据Token删除储存在Redis缓存中的用户信息", response=ResponseResult.class)
	@ApiImplicitParam(name="token", value="Cookie上的token信息", required=true, dataType="String")
	@GetMapping(value="deleteRedisSessionUser/{token}")
	public Object deleteRedisSessionUser(@PathVariable String token) {
		String string = jedisClient.get(SSO_REDIS_SESSION_KEY+token) ;
		User user = JSON.parseObject(string, User.class);
		jedisClient.del(SSO_REDIS_SESSION_KEY+token) ;
		logger.info("用户退出登陆【用户名：{},IP：{},时间：{}】", user.getUsername(), WebUtil.getIpAddress(request), DateUtil.getCurrentDateTimeString());
		return setResponseResultOk() ;
	}
	
}
